﻿Public Module Module1

    Function GetFileFullName(ByVal File As String) As String
        Try
            Return New IO.FileInfo(File).Name
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
    Function GetFileExtension(ByVal File As String) As String
        Return New IO.FileInfo(File).Extension
    End Function
    Function GetFileName(ByVal File As String) As String
        Try
            Dim FileName As String = GetFileFullName(File)
            Dim Extension As String = GetFileExtension(File)
            Return FileName.Remove(Len(FileName) - Len(Extension))
        Catch ex As Exception
            Return Nothing
        End Try
    End Function
    Function GetFileDirectoryName(ByVal File As String) As String
        Try
            Dim DirectoryName As String = New IO.FileInfo(File).DirectoryName
            If DirectoryName.EndsWith("\") = False Then DirectoryName &= "\"
            Return DirectoryName
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    Public Function GetSimilarityList(key As String, ByVal work As Dictionary(Of Integer, Row), Optional minSimilarityLong As Double = 85, Optional minSimilarityShort As Double = 70, Optional maxToleranceLong As Double = 20, Optional maxToleranceShort As Double = 10) As List(Of CompareResult)
        Return GetSimilarityList(key, work, New Dictionary(Of String, List(Of DataValue)), minSimilarityLong, minSimilarityShort, maxToleranceLong, maxToleranceShort)
    End Function
    Public Function GetSimilarityList(key As String, data As Dictionary(Of String, List(Of DataValue)), Optional minSimilarityLong As Double = 85, Optional minSimilarityShort As Double = 70, Optional maxToleranceLong As Double = 20, Optional maxToleranceShort As Double = 10) As List(Of CompareResult)
        Return GetSimilarityList(key, New Dictionary(Of Integer, Row), data, minSimilarityLong, minSimilarityShort, maxToleranceLong, maxToleranceShort)
    End Function
    Public Function GetSimilarityList(key As String, ByVal work As Dictionary(Of Integer, Row), data As Dictionary(Of String, List(Of DataValue)), Optional minSimilarityLong As Double = 85, Optional minSimilarityShort As Double = 70, Optional maxToleranceLong As Double = 20, Optional maxToleranceShort As Double = 10) As List(Of CompareResult)
        Dim List As New List(Of CompareResult)

        For Each row In work
            If Not row.Value.Show OrElse row.Value.Target = "" OrElse row.Value.Source = row.Value.Target Then Continue For
            With Compare(key, row.Value.Source, minSimilarityLong, minSimilarityShort, maxToleranceLong, maxToleranceShort)
                If .IsEqual AndAlso (List.Count = 0 OrElse Not List.Exists(Function(item) item.Source = row.Value.Source AndAlso item.Target = row.Value.Target)) Then
                    List.Add(New CompareResult(row.Value.Source, row.Value.Target, .Similarity, .Tolerance, 1))
                End If
            End With
        Next

        For Each row In data
            With Compare(key, row.Key, minSimilarityLong, minSimilarityShort, maxToleranceLong, maxToleranceShort)
                If .IsEqual AndAlso (List.Count = 0 OrElse Not List.Exists(Function(item) item.Source = row.Key AndAlso item.Target = DataBase.GetItem(data, row.Key))) Then
                    List.Add(New CompareResult(row.Key, DataBase.GetItem(data, row.Key), .Similarity, .Tolerance, 2))
                End If
            End With
        Next

        If List.Count > 1 Then
            Return List.OrderByDescending(Function(item) item.Similarity).ThenBy(Function(item) item.Tolerance).ToList
        Else
            Return List
        End If

    End Function

    Public Function Compare(text1 As String, text2 As String) As CompareResult
        Return Compare(text1, text2,,,,)
    End Function
    Public Function Compare(text1 As String, text2 As String, Optional minSimilarityLong As Double = 85, Optional minSimilarityShort As Double = 70, Optional maxToleranceLong As Double = 20, Optional maxToleranceShort As Double = 10) As CompareResult
        Dim minSimilarity As Double = minSimilarityLong
        Dim maxTolerance As Double = maxToleranceLong

        'Remove repeat space
        text1 = RemoveDuplicateSpace(text1).ToLower
        text2 = RemoveDuplicateSpace(text2).ToLower

        'Get text length
        Dim len1 As Double = text1.Length
        Dim len2 As Double = text2.Length

        'Long text save to temp1, sort text save to temp2
        Dim temp1 As String = If(len1 >= len2, text1, text2)
        Dim temp2 As String = If(len1 < len2, text1, text2)

        'Big length save to len1, small length save to len2
        len1 = temp1.Length
        len2 = temp2.Length

        Dim tempLen As Double = 0
        Dim similarityPercent As Double = 0

        Dim lastIndex As Integer = 0
        Dim toleranceCount As Double = 0
        Dim tolerancePercent As Double = 0

        If len1 > 0 Then 'At least one of them has content

            'Compare big length
            If len1 < 8 Then
                minSimilarity = minSimilarityShort
                maxTolerance = maxToleranceShort
            End If

            'Remove same part with temp2 in temp1
            For Each c As Char In temp2.ToCharArray()
                Dim ind As Integer = -1
                ind = temp1.IndexOf(c)

                If ind >= 0 Then
                    temp1 = temp1.Remove(ind, 1)

                    If ind < lastIndex Then
                        toleranceCount += 1
                    End If

                    lastIndex = ind
                End If
            Next

            'Calculate similarityPercent
            tempLen = temp1.Length
            similarityPercent = 100 - ((tempLen / len1) * 100)

            'Calculate tolerancePercent
            If len2 > 0 Then
                tolerancePercent = (toleranceCount / len2) * 100
            Else
                tolerancePercent = 0
            End If
        Else
            'Set similarityPercent & tolerancePercent
            similarityPercent = 100
            tolerancePercent = 0
        End If

        'Compare values
        Return New CompareResult(similarityPercent >= minSimilarity AndAlso tolerancePercent <= maxTolerance, similarityPercent, tolerancePercent)
    End Function
    Public Function RemoveDuplicateSpace(text As String) As String
        text = Trim(text)
        While text.Contains("  ")
            text = text.Replace("  ", " ")
        End While
        Return text
    End Function
End Module